﻿#pragma once

#include "GameCoreScriptBinder.h"
#include "PhysXObj.h"
#include "PhysicsTerrain.h"
#include "PhysTriggerReport.h"


_NAMESPACE_BEGIN

class PhysicsLib_ScriptBinder
{
public:
	SINGLETON_HELPER(PhysicsLib_ScriptBinder);
	PhysicsLib_ScriptBinder();
protected:
	void BindPhysX(asIScriptEngine* engine);
private:
};

REGISTER_TYPEMETHODS(PhysicsManager)
{
	BASEMETHODS(type,T,Panel)
	r=engine->RegisterObjectMethod(type,"void InitialNX(NxSceneDesc& in)",asMETHOD(T,InitialNx), asCALL_THISCALL);	 assert( r >= 0 );
	r=engine->RegisterObjectMethod(type,"void ConnectToRemoteDebuger()",asMETHOD(T,ConnectToRemoteDebuger), asCALL_THISCALL);	 assert( r >= 0 );
	r=engine->RegisterObjectMethod(type,"NxScene @GetWorldScene()",asMETHOD(T,GetWorldScene), asCALL_THISCALL);	 assert( r >= 0 );
	r=engine->RegisterObjectMethod(type,"void SetSpeed(float)",asMETHOD(T,SetSpeed), asCALL_THISCALL);	 assert( r >= 0 );
	r=engine->RegisterObjectMethod(type,"void AddObj(PhysXObj@)",asMETHOD(T,AddObj), asCALL_THISCALL);	 assert( r >= 0 );
	r=engine->RegisterObjectMethod
		(type,"void LoadPhysMesh(const string&in,const string&in,const NxVec3&in)",
		asMETHOD(T,LoadPhysMesh), asCALL_THISCALL);	 assert( r >= 0 );
}

REGISTER_TYPEMETHODS(Shape_Desc)
{		
	r = engine->RegisterObjectProperty(type, "NxMat34 localPose",offsetof(T,localPose)); assert( r >= 0 );	
}

REGISTER_TYPEMETHODS(Cube_Desc)
{
	BASEMETHODS(type,T,Shape_Desc)
	r = engine->RegisterObjectProperty(type, "NxVec3 size",offsetof(T,size)); assert( r >= 0 );	
}

REGISTER_TYPEMETHODS(PhysXPrimitive)
{
	r = engine->RegisterObjectProperty(type, "NxShape@ pshape",offsetof(T,pshape)); assert( r >= 0 );	
	r = engine->RegisterObjectMethod(type,"NxMat34 GetLocalPose()",asMETHOD(T,GetLocalPose),asCALL_THISCALL);	 assert( r >= 0 );				
	r = engine->RegisterObjectMethod(type,"NxVec3 GetAABB()",asMETHOD(T,GetAABB),asCALL_THISCALL);	 assert( r >= 0 );	
}

REGISTER_TYPEMETHODS(CubeShape)
{
	BASEMETHODS(type,T,PhysXPrimitive)
	r = engine->RegisterObjectMethod(type,"void SetSize(float,float,float)",asMETHOD(T,SetSize),asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod(type,"NxVec3 GetSize()",asMETHOD(T,GetSize),asCALL_THISCALL);	 assert( r >= 0 );
}

REGISTER_TYPEMETHODS(Sphere_Desc)
{
	BASEMETHODS(type,T,Shape_Desc)
	r = engine->RegisterObjectProperty(type, "float radius",offsetof(T,radius)); assert( r >= 0 );	
}

REGISTER_TYPEMETHODS(SphereShape)
{
	BASEMETHODS(type,T,PhysXPrimitive)
	r = engine->RegisterObjectMethod(type,"void SetRadius(float)",asMETHOD(T,SetRadius),asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod(type,"float GetRadius()",asMETHOD(T,GetRadius),asCALL_THISCALL);	 assert( r >= 0 );
}

REGISTER_TYPEMETHODS(Capsule_Desc)
{
	BASEMETHODS(type,T,Shape_Desc)
	r = engine->RegisterObjectProperty(type, "float radius",offsetof(T,radius)); assert( r >= 0 );	
	r = engine->RegisterObjectProperty(type, "float height",offsetof(T,height)); assert( r >= 0 );	
}

REGISTER_TYPEMETHODS(CapsuleShape)
{
	BASEMETHODS(type,T,PhysXPrimitive)
	r = engine->RegisterObjectMethod(type,"void SetParam(float,float)",asMETHOD(T,SetParam),asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod(type,"float GetHeight()",asMETHOD(T,GetHeight),asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod(type,"float GetRadius()",asMETHOD(T,GetRadius),asCALL_THISCALL);	 assert( r >= 0 );
}

REGISTER_TYPEMETHODS(Wheel_Desc)
{
	BASEMETHODS(type,T,Shape_Desc)
}

REGISTER_TYPEMETHODS(WheelShape)
{
	BASEMETHODS(type,T,PhysXPrimitive)
	r = engine->RegisterObjectMethod(type,"void SetParam(float)",asMETHOD(T,SetParam),asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod(type,"float GetWidth()",asMETHOD(T,GetWidth),asCALL_THISCALL);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod(type,"float GetRadius()",asMETHOD(T,GetRadius),asCALL_THISCALL);	 assert( r >= 0 );
	/*	r = engine->RegisterObjectMethod(type,"void setMotorTorque(float)",asMETHOD(T,setMotorTorque),asCALL_THISCALL);	 assert( r >= 0 );*/
}

REGISTER_TYPEMETHODS(Plane_Desc)
{
	BASEMETHODS(type,T,Shape_Desc)
	r = engine->RegisterObjectProperty(type, "float width",offsetof(T,width)); assert( r >= 0 );
	r = engine->RegisterObjectProperty(type, "float length",offsetof(T,length)); assert( r >= 0 );
}		

REGISTER_TYPEMETHODS(PlaneShape)
{
	BASEMETHODS(type,T,PhysXPrimitive)
	//r = engine->RegisterObjectMethod(type,"void SetParam(const float3&in,const float3&in)",asMETHOD(T,SetParam),asCALL_THISCALL);	 assert( r >= 0 );
}

REGISTER_TYPEMETHODS(Terrain_Desc)
{
	BASEMETHODS(type,T,Shape_Desc)
		r = engine->RegisterObjectProperty(type, "NxVec3 pos",offsetof(T,pos)); assert( r >= 0 );	
	r = engine->RegisterObjectProperty(type, "NxVec3 size",offsetof(T,size)); assert( r >= 0 );	
	r = engine->RegisterObjectProperty(type, "uint nbRows",offsetof(T,nbRows)); assert( r >= 0 );	
	r = engine->RegisterObjectProperty(type, "uint nbColumns",offsetof(T,nbColumns)); assert( r >= 0 );	
	r = engine->RegisterObjectProperty(type, "float width",offsetof(T,width)); assert( r>=0 );
	r = engine->RegisterObjectProperty(type, "float height",offsetof(T,height)); assert( r>=0 );
	r = engine->RegisterObjectProperty(type, "string nameHeightmap",offsetof(T,nameHeightmap)); assert( r >= 0 );
}	

REGISTER_TYPEMETHODS(NxShapeDesc)
{
	r = engine->RegisterObjectProperty(type, "NxMat34 localPose", offsetof(T,localPose)); assert( r >= 0 );
	r = engine->RegisterObjectProperty(type, "uint shapeFlags", offsetof(T,shapeFlags)); assert( r >= 0 );

}

REGISTER_TYPEMETHODS(NxBoxShapeDesc)
{
	BASEMETHODS(type,T,NxShapeDesc)
	r = engine->RegisterObjectProperty(type, "NxVec3 dimensions", offsetof(T,dimensions)); assert( r >= 0 );
}

REGISTER_TYPEMETHODS(NxPlaneShapeDesc)
{
	BASEMETHODS(type,T,NxShapeDesc)
	r = engine->RegisterObjectProperty(type, "NxVec3 normal", offsetof(T,normal)); assert( r >= 0 );
	r = engine->RegisterObjectProperty(type, "float d", offsetof(T,d)); assert( r >= 0 );
}

REGISTER_TYPEMETHODS(NxActorDescBase)
{
	r = engine->RegisterObjectProperty(type, "NxMat34 globalPose", offsetof(T,globalPose)); assert( r >= 0 );		 
	r = engine->RegisterObjectMethod(type,"void setToDefault()",asMETHOD(T,setToDefault),asCALL_THISCALL);	 assert( r >= 0 );
}

extern void NxActorDesc_SetBodyDesc(NxActorDesc* self,const NxBodyDesc& body);	
extern void NxActorDesc_AddShape(NxActorDesc* self,NxShapeDesc& shape);

REGISTER_TYPEMETHODS(NxActorDesc)
{
	BASEMETHODS(type,T,NxActorDescBase)
	r = engine->RegisterObjectMethod(type,"void AddShape(const NxShapeDesc& in)",asFUNCTION(NxActorDesc_AddShape), asCALL_CDECL_OBJFIRST);	 assert( r >= 0 );
	r = engine->RegisterObjectMethod(type,"void SetBodyDesc(const NxBodyDesc& in)",asFUNCTION(NxActorDesc_SetBodyDesc), asCALL_CDECL_OBJFIRST);	 assert( r >= 0 );
	r = engine->RegisterObjectProperty(type, "float density", offsetof(T,density)); assert( r >= 0 );
}

REGISTER_TYPEMETHODS(NxJoint)
{
	r = engine->RegisterObjectMethod(type,"void setBreakable(float,float)",asMETHOD(T,setBreakable), asCALL_THISCALL);	 assert( r >= 0 );			
}

REGISTER_TYPEMETHODS(NxD6Joint)
{
	BASEMETHODS(type,T,NxJoint)
	r = engine->RegisterObjectMethod(type,"void saveToDesc(NxD6JointDesc&out)",
		asMETHOD(T,saveToDesc), asCALL_THISCALL);	 assert( r >= 0 );	

	r = engine->RegisterObjectMethod(type,"void setDriveOrientation(const NxQuat&in)",
		asMETHOD(T,setDriveOrientation), asCALL_THISCALL);	 assert( r >= 0 );	

	r = engine->RegisterObjectMethod(type,"void loadFromDesc(const NxD6JointDesc& in)",
		asMETHOD(NxD6Joint,loadFromDesc), asCALL_THISCALL);	 assert( r >= 0 );	

	r = engine->RegisterObjectMethod(type,"NxVec3 getGlobalAnchor()",
		asMETHOD(NxD6Joint,getGlobalAnchor), asCALL_THISCALL);	 assert( r >= 0 );
}//getGlobalAnchor()

REGISTER_TYPEMETHODS(NxD6JointDesc)
{
	r = engine->RegisterObjectProperty(type, "NxQuat driveOrientation",offsetof(T,driveOrientation)); assert( r >= 0 );	
	r = engine->RegisterObjectProperty(type, "NxActor @actor0", offsetof(T,actor)); assert( r >= 0 );
	r = engine->RegisterObjectProperty(type, "NxActor @actor1", offsetof(T,actor)+4); assert( r >= 0 );
	r = engine->RegisterObjectProperty(type, "NxVec3 localAnchor0", offsetof(T,localAnchor)); assert( r >= 0 );
	r = engine->RegisterObjectProperty(type, "NxVec3 localAnchor1", offsetof(T,localAnchor)+sizeof(NxVec3)); assert( r >= 0 );
	r = engine->RegisterObjectProperty(type, "NxJointDriveDesc slerpDrive", offsetof(T,slerpDrive)); assert( r >= 0 );
	r = engine->RegisterObjectProperty(type, "NxJointDriveDesc twistDrive", offsetof(T,twistDrive)); assert( r >= 0 );
	r = engine->RegisterObjectProperty(type, "NxJointDriveDesc xDrive", offsetof(T,xDrive)); assert( r >= 0 );

}

REGISTER_TYPEMETHODS(PhysXObj)
{	
	r = engine->RegisterObjectMethod(type,"NxActor@ GetActor( )",
		asMETHOD(T,GetActor), asCALL_THISCALL);	 assert( r >= 0 );		

	r = engine->RegisterObjectMethod(type,"PhysXPrimitive@ GetShape(int)",
		asMETHOD(T,GetShape), asCALL_THISCALL);	 assert( r >= 0 );		

	r = engine->RegisterObjectMethod(type,"void SetScriptObj(EventHandler@)",
		asMETHOD(T,SetScriptObj),asCALL_THISCALL);	 assert( r >= 0 );

	r = engine->RegisterObjectMethod(type,"void SetMesh(int,const string&in,const string&in)",
		asMETHOD(T,SetMesh), asCALL_THISCALL);	 assert( r >= 0 );			

	r = engine->RegisterObjectMethod(type,"void ScaleMesh(int,const Vector3&in )",
		asMETHOD(T,ScaleMesh), asCALL_THISCALL);	 assert( r >= 0 );			

	r = engine->RegisterObjectMethod(type,"void Show(bool)",
		asMETHOD(T,Show), asCALL_THISCALL);	 assert( r >= 0 );		

	r = engine->RegisterObjectMethod(type,"void SetPos(float,float,float)",
		asMETHOD(T,SetPos), asCALL_THISCALL);	 assert( r >= 0 );		
}

REGISTER_TYPEMETHODS(PhysPlane)
{
	BASEMETHODS(type,T,PhysXObj)
	r = engine->RegisterObjectMethod(type,"void Create(const NxVec3&in)",
		asMETHOD(T,Create), asCALL_THISCALL);	 assert( r >= 0 );			

}

REGISTER_TYPEMETHODS(PhysTerrain)
{
	BASEMETHODS(type,T,PhysXObj)

	r = engine->RegisterObjectMethod(type,"void Create(const NxVec3&in)",
		asMETHOD(T,Create), asCALL_THISCALL);	 assert( r >= 0 );			
	r = engine->RegisterObjectMethod(type,"void CreateFromOhm(const NxVec3&in,const string&in,int,int)",
		asMETHOD(T,CreateFromOhm), asCALL_THISCALL);	 assert( r >= 0 );		
}

REGISTER_TYPEMETHODS(NxVehicleDesc)
{
	r = engine->RegisterObjectMethod(type,
		"void setCommonUsing(const NxVec3&in,bool,bool,bool,bool,bool)",
		asMETHOD(T,setCommonUsing), asCALL_THISCALL);	 assert( r >= 0 );			
}

REGISTER_TYPEMETHODS(PhysCar)
{
	BASEMETHODS(type,T,PhysXObj)

	r = engine->RegisterObjectMethod(type,
		"void Create(const string&in,const string&in,const string&in,const NxVehicleDesc&in)",
		asMETHOD(T,Create), asCALL_THISCALL);	 assert( r >= 0 );			

	r = engine->RegisterObjectMethod(type,"void SetCtrled(bool)",
		asMETHOD(T,SetCtrled), asCALL_THISCALL);	 assert( r >= 0 );	

	r = engine->RegisterObjectMethod(type,"void UseCamera(bool)",
		asMETHOD(T,UseCamera), asCALL_THISCALL);	 assert( r >= 0 );	

	r = engine->RegisterObjectMethod(type,
		"void SetMeshOffset(const Vector3&in,const Vector3&in,const Vector3&in,const Vector3&in,const Vector3&in)",
		asMETHOD(T,SetMeshOffset), asCALL_THISCALL);	 assert( r >= 0 );	
	
}

REGISTER_TYPEMETHODS(PhysBox)
{
	BASEMETHODS(type,T,PhysXObj)

	r = engine->RegisterObjectMethod(type,
		"void Create(const NxVec3&in,const NxVec3&in)",
		asMETHOD(T,Create), asCALL_THISCALL);	 assert( r >= 0 );			

	r = engine->RegisterObjectMethod(type,
		"void ResertMeshSize( )",
		asMETHOD(T,ResertMeshSize), asCALL_THISCALL);	 assert( r >= 0 );		

}

REGISTER_TYPEMETHODS(TriggerEvent)
{
	BASEMETHODS(type,T,ASEvent)
}

_NAMESPACE_END